// Global Variables
let app = null;

// listen for messages from the user's current tab
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    // TODO: Implement this
    // User is browsing the web app and may click a thread link to open it while the extension is open.
    if (request?.action === 'cunext_prime_thread') {
        const thread_id = request?.thread_id || null;
        const url = request?.url || null;
        const chat_id = request?.chat_id || null;
        app.primeThread(thread_id, url, chat_id);
        // Respond with success
        sendResponse({ success: true });
    }
});

$('document').ready(function() {

    // copied from base.js
    $('body').on('click', function(e) {
        const target = $(e.target);
        const closestThread = target.closest('.thread');
        const closestChat = target.closest('.chat');
        const parent = closestThread.length > 0 ? closestThread : closestChat.length > 0 ? closestChat : null;
        if (!parent) return;
        if (target.hasClass('blur')) target.removeClass('blur');
        if (target.hasClass('blocked')) target.removeClass('blocked');
        if (target.hasClass('reported')) target.removeClass('reported');
    });

    // Prevent loss of navigation ability caused by chat_options.js functions
    $('body').on('click', '.chat-options-action-link', function(){
        const threadContainerParent = $(this).closest('.thread-container');
        if(threadContainerParent.length > 0){
            app.getThreads();
        }
    });

    // Update #server_now_utc value
    try {
        const serverNowUTC = new Date().toISOString();
        $('#server_now_utc').val(serverNowUTC);
    } catch (e) {
        console.error(e);
    }

    // load icons from bsi
    render_bsi();

    // Initialize app state
    app = new AppState();
    app.applyFontSizeSetting();

    // Get current user url and load threads, also, start notification polling
    setTimeout(() => {
        chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
            const currentTab = tabs[0];
            if (currentTab) {
                try {
                    app.getThreads(currentTab.url);
                } catch (e) {
                    console.error(e);
                }
            }
        });

        // Notification polling
        app.checkForNotifications();
        setInterval(() => {
            if (app) {
                app.checkForNotifications();
            }
        }, 30000); // Check for notifications every 30 seconds
    }, 200); // Wait for app to initialize

    // listeners
    // NOTE: use arrow functions to preserve "this" context inside app class
    $('#settings_opener').on('click', () => app.buildSettingsForm());
    $('#thread_locker').on('click', (e) => {
        e.preventDefault();
        if (app.toggleThreadLock()) { // locked if returns true
            $('#thread_locker').animate({ opacity: '0' }, 300, function() {
                $('#thread_locker').addClass('locked').removeClass('unlocked').empty().append('<span class="bi bi-unlock"></span>&nbsp;Unlock');
                render_bsi();
                $('#thread_locker').animate({ opacity: '1' }, 500);
            });
        } else {
            $('#thread_locker').animate({ opacity: '0' }, 300, function() {
                $('#thread_locker').addClass('unlocked').removeClass('locked').empty().append('<span class="bi bi-lock"></span>&nbsp;Lock');
                render_bsi();
                $('#thread_locker').animate({ opacity: '1' }, 500);
            });
        }
    });
    $('#get_threads_link').on('click', (e) => {
        e.preventDefault();
        app.getThreads();
    });

    // Prevent default link_to_thread behavior
    $(document).on('click', '.link_to_thread', (e) => {
        e.preventDefault();
        // Clone .thread parent
        const $this = $(e.currentTarget);
        const $thread = $this.closest('.thread');
        // Get all data attributes from $thread
        const dataAttrs = $thread.data();
        for (const key in dataAttrs) {
            dashKey = key.replace(/([A-Z])/g, '-$1').toLowerCase();
            $('#thread-container').attr(`data-${dashKey}`, dataAttrs[key]);
        }
        setTimeout(() => {
            render_threads(app.getSetting('server_url'), (e) => { // exit callback
                e.preventDefault();
                if (app.lockedThreadId) { // unlock
                    $('#thread_locker').trigger('click');
                }
                setTimeout(function() {
                    $('#get_threads_link').trigger('click');
                }, 100);
            });
        }, 30);
        const chatId = $this.attr('data-chat-id');
        const authorPK = $this.attr('data-author-public-key');
        app.loadThread(chatId, authorPK);
    });

    // Track when the user's current url changes and load threads for the new page (new tab, new page, etc.)
    var setWebNavListeners = setInterval(() => {
        // app is loaded when page ready.
        if (!app) return;
        if (!chrome || !chrome.webNavigation) return;

        // Monitor when a user navigates to a new page in the current tab
        chrome.webNavigation.onCompleted.addListener((details) => {
            // app is loaded when page ready.
            if (!app) return;
            chrome.tabs.get(details.tabId, (tab) => {
                // return if tab not active
                if (!tab.active) return;
                try {
                    app.getThreads(tab.url);
                } catch (e) {
                    console.error(e);
                }
            });
        });

        // Add a listener for sites that use pushState to change the URL without reloading the page.
        chrome.webNavigation.onHistoryStateUpdated.addListener((details) => {
            // app is loaded when page ready.
            if (!app) return;
            chrome.tabs.get(details.tabId, (tab) => {
                // return if tab not active
                if (!tab.active) return;
                try {
                    app.getThreads(tab.url);
                } catch (e) {
                    console.error(e);
                }
            });
        });
        clearInterval(setWebNavListeners);
        setWebNavListeners = null;
    }, 100);

    // Listen for navigation on current tab
    chrome.tabs.onActivated.addListener((activeInfo) => {
        // app is loaded when page ready.
        if (!app) return;
        chrome.tabs.get(activeInfo.tabId, (tab) => {
            // return if tab not active
            if (!tab.active) return;
            try {
                app.getThreads(tab.url);
            } catch (e) {
                console.error(e);
            }
        });
    });

    // Listen for new tab creation
    chrome.tabs.onCreated.addListener((tab) => {
        // app is loaded when page ready.
        if (!app) return;
        // return if tab not active
        if (!tab.active) return;
        try {
            app.getThreads(tab.url);
        } catch (e) {
            console.error(e);
        }
    });
});
